#!/bin/perl
# Leandro Linardos | 89567

###############################################################################
#
# Código destinado a parseo de opciones por linea de comando y validación de 
# formato y valor de datos de entrada.
#
###############################################################################

use Getopt::Std;            # uso getopts para parsear la entrada

#
# True si el valor es un entero positivo o 0
#
sub is_integer {
    return 1 if ($_ =~ m/^[0-9]+$/);
    return 0;
}


#
# Valida formato de opcion -f. Beneficiarios.
# Carga contenedores globales y setea variables de error.
#
sub validate_beneficiaries_option_format {
    my @files = split(" ", $FILES_OPTION); 
    my $ls_expr = "";
    foreach (@files) {
        if ( $_ eq "*") {
            $ls_expr = "benef.*";
        } elsif ( index($_, 'benef.') >= 0 ) {
            if ( index($_, '*') > 5) {
                $ls_expr = $_;
            } else {
                push(@IN_BENEF_FILES, $_);
            }
        } else {
            $ERROR_STATUS = 1;
            $ERROR_MSG  = "Archivos de beneficiarios solo con formato: ";
            $ERROR_MSG .= "benef.* o * para todos los beneficiarios.";
        }
    }
    if ($ls_expr ne "") {
        my $ls_ret = `cd ${BENEFICIARIES_DIR}; ls -1 $ls_expr 2> /dev/null  `;
        my @files = split("\n", $ls_ret);
        push(@IN_BENEF_FILES, @files);
    }
}


#
# Valida el formato de opción -a. Agencias.
# Carga contenedores globales y setea variables de error.
#
sub validate_agencies_option_format {
    my @agencies = split(" ", $AGENCIES_OPTION);
    my $all_agencies = 0; 
    foreach ( @agencies ) {
        if ( $_ eq "*" ) {
            $AGENCIES_OPTION = "";
            $all_agencies = 1;
        } elsif ( is_integer( $_ ) ) {
            my $id = int($_);
            %AGENCIES_FILTERS->{ $id } = 1;
        } else {
            $ERROR_STATUS = 1;
            $ERROR_MSG = "($_) El ID de agencia debe ser númerico o bien * ";
            $ERROR_MSG .= "para todas las agencias.";
        }
    }
    if ( ( $all_agencies != 0 ) && ( $#AGENCIES_FILTERS != -1 ) ) {
        $ERROR_STATUS = 1;
        $ERROR_MSG =  "No se permiten especificar beneficios si se usa *.";
    }
}


#
# Valida el formato de opción -b. Beneficios.
# Carga contenedores globales y setea variables de error.
#
sub validate_benefits_option_format {
    my @benefits = split(" ", $BENEFITS_OPTION);
    my $all_benefits = 0; 
    foreach ( @benefits ) {
        if ( $_ eq "*" ) {
            $BENEFITS_OPTION = "";
            $all_benefits = 1;
        } elsif ( is_integer( $_ ) ) {
            my $id = int($_);
            %BENEFITS_FILTERS->{ $id } = 1;
        } else {
            $ERROR_STATUS = 1;
            $ERROR_MSG = "($_) El ID de beneficio debe ser númerico o bien * ";
            $ERROR_MSG .= "para todos los beneficios.";
        }
    }
    if ( $all_benefits && $#BENECIES_FILTERS != -1) {
        $ERROR_STATUS = 1;
        $ERROR_MSG =  "No se permiten especificar beneficios si se usa *.";
    }
}


#
# Valida el formato de opción -e. Estado.
# Carga contenedores globales y setea variables de error.
#
sub validate_state_option_format {
    for(my $i = 0; $i < length($E_FLAG); $i++) {
        my $c = substr $E_FLAG, $i, 1;
        if($c eq "a") {
            %STATE_FILTERS->{ "aprobado" } = 1;
        } elsif ($c eq "r") {
            %STATE_FILTERS->{ "rechazado" } = 1;
        } elsif ($c eq "p") {
            %STATE_FILTERS->{ "pendiente" } = 1;
        } else {
            $ERROR_STATUS = 1;
            $ERROR_MSG = "($c) Valores válidos para opción -e son: 'a', 'r', ";
            $ERROR_MSG .= "'p' y combinaciones de los mismos.";
        }
    }
}


#
# Parsea las opciones de la línea de comandos seteando los correspondientes 
# flags.
#
sub parse_options {
    %options=();
    getopts("tdce:f:a:b:h",\%options);
    
    if ( keys( %options ) eq 0 ) {
        $ERROR_STATUS = 1;
        $ERROR_MSG = "Debe indicar por lo menos un archivo de beneficiarios.";    
    }
    return if $ERROR_STATUS != 0;
    
    $H_FLAG = 1 if defined $options{h};
    $D_FLAG = 1 if defined $options{d};
    $T_FLAG = 1 if defined $options{t};
    $C_FLAG = 1 if defined $options{c};
    $E_FLAG = $options{e} if defined $options{e};
    $FILES_OPTION = $options{f} if defined $options{f};
    $BENEFITS_OPTION = $options{b} if defined $options{b};
    $AGENCIES_OPTION = $options{a} if defined $options{a};
    foreach ( @ARGV ) {
        $ERROR_STATUS = 1;
        $ERROR_MSG = "($_) No se acepta paso de parámetros. Usar opciones.";
    }    
    return if $ERROR_STATUS != 0;
    
    # resuelvo opciones -t y -d
    $T_FLAG = 1 if not $T_FLAG and not $D_FLAG;

    # resuelvo incosistencias de opciones
    if ($E_FLAG and not $C_FLAG) {
        $ERROR_STATUS = 1;
        $ERROR_MSG = "Opción -e sólo se permite en conjunto con opción -c.";
    }
    return if $ERROR_STATUS != 0;
    
    do validate_beneficiaries_option_format();
    return if $ERROR_STATUS != 0;

    do validate_agencies_option_format();
    return if $ERROR_STATUS != 0;

    do validate_benefits_option_format();
    return if $ERROR_STATUS != 0;
    
    do validate_state_option_format();
    return if $ERROR_STATUS != 0;
}


#
# Devuelve el id de beneficio correspondiente al codigo pasado
#
sub get_id_benef_by_code {
    my $code = $_[0];
    my %benefits; 
    open(BENEFITS, "<$BENEFITS_MASTER_FILE") or die "Error";
    while (my $line = <BENEFITS>) {
        chop($line);
        my @fields = split(",", $line);
        %benefits->{ $fields[1] } = $fields[0];
    }
    close BENEFITS;
    return $benefits{$code};
}


#
# Valida los id de agencia con el archivo maestro.
# Setea variables de error en caso de error.
#
sub validate_agencies_filters {
    my $agencies = do get_agencies();
    for my $key (keys %AGENCIES_FILTERS ) {
        if (not $$agencies{ $key }) {
            $ERROR_STATUS = 3;
            $ERROR_MSG = "ID de agencia invalido: $key";
        }
    }
}


#
# Valida los id de beneficio con el archivo maestro.
# Setea variables de error en caso de error.
#
sub validate_benefits_filters {
    my $benefits = do get_benefits();
    for my $key (keys %BENEFITS_FILTERS ) {
        if (not $$benefits{ $key }) {
            $ERROR_STATUS = 3;
            $ERROR_MSG = "ID de beneficio invalido: $key";
        }
    }
}


#
# Valida los archivos de beneficiarios.
# Setea variables de error en caso de error.
#
sub validate_beneficiaries_files {
    if( $#IN_BENEF_FILES eq -1 ) {
        $ERROR_STATUS = 3;
        $ERROR_MSG = "Debe indicar por lo menos un archivo de beneficiarios (-f)";        
    }
    foreach ( @IN_BENEF_FILES ) {
        if (not -e "$BENEFICIARIES_DIR/$_") {
            $ERROR_STATUS = 2;
            $ERROR_MSG = "Archivo de beneficiarios inexistente: $_";        
        }
    }
}


#
# Devuelve un nuevo núumero secuencial para los archivos.
#
sub get_new_sequence_number {
    my $ls_ret = `cd ${OUTPUT_DIR}; ls -1 plist.* 2> /dev/null`;
    my @ls_array = split("\n", $ls_ret);
    return "0001" if $#ls_array == -1;
    sort @ls_array;
    my $last = pop @ls_array;
    $last = substr($last, length "plist.", 4);
    $last++;
    return $last;
}

1; # return value = true pedido por Perl
